package ${packagePrefix}.config;

import ${packagePrefix}.common.exception.GlobalExceptionHandler;
import ${packagePrefix}.common.filter.RequestLoggingFilter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
<#if specialRequirements?? && specialRequirements?contains("安全")>
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
</#if>
<#if specialRequirements?? && specialRequirements?contains("跨域")>
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
</#if>
<#if specialRequirements?? && specialRequirements?contains("异步")>
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;
</#if>

<#if generateComments>
/**
 * 应用全局配置类
 * <p>
 * 该配置类提供了应用级别的全局配置，包括跨域配置、异步线程池、
 * 缓存管理、Jackson序列化、请求日志等功能。
 * </p>
 *
 * @author Auto Generated
 */
</#if>
@Configuration
@EnableCaching
@EnableAsync
@EnableScheduling
public class ApplicationConfig implements WebMvcConfigurer {

    /**
     * 配置ObjectMapper
     */
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 处理Java 8日期时间API
        objectMapper.registerModule(new JavaTimeModule());
        // 不将日期序列化为时间戳
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // 忽略空Bean转换异常
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        return objectMapper;
    }
    
    /**
     * 请求日志过滤器
     */
    @Bean
    public FilterRegistrationBean<RequestLoggingFilter> requestLoggingFilter() {
        FilterRegistrationBean<RequestLoggingFilter> registrationBean = new FilterRegistrationBean<>();
        registrationBean.setFilter(new RequestLoggingFilter());
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }
    
    /**
     * 全局异常处理器
     */
    @Bean
    public GlobalExceptionHandler globalExceptionHandler() {
        return new GlobalExceptionHandler();
    }
    
    /**
     * 跨域配置
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH")
                .allowedHeaders("*")
                .maxAge(3600);
    }
    
<#if specialRequirements?? && specialRequirements?contains("跨域")>
    /**
     * CORS过滤器配置
     */
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*");  // 允许所有域名访问
        corsConfiguration.addAllowedHeader("*");  // 允许所有请求头
        corsConfiguration.addAllowedMethod("*");  // 允许所有HTTP方法
        corsConfiguration.setAllowCredentials(true);  // 允许发送凭证
        corsConfiguration.setMaxAge(3600L);  // 预检请求的有效期，单位为秒
        
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfiguration);
        
        return new CorsFilter(source);
    }
</#if>
    
<#if specialRequirements?? && specialRequirements?contains("异步")>
    /**
     * 异步执行线程池
     */
    @Bean("taskExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数
        executor.setCorePoolSize(10);
        // 最大线程数
        executor.setMaxPoolSize(20);
        // 队列容量
        executor.setQueueCapacity(200);
        // 线程前缀名
        executor.setThreadNamePrefix("async-executor-");
        // 拒绝策略：调用者运行策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务完成后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        // 等待时间（默认为0，此时立即停止）
        executor.setAwaitTerminationSeconds(60);
        // 初始化
        executor.initialize();
        return executor;
    }
</#if>
    
<#if specialRequirements?? && specialRequirements?contains("安全")>
    /**
     * 密码编码器
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
</#if>
    
<#if specialRequirements?? && specialRequirements?contains("国际化")>
    /**
     * 国际化配置
     */
    @Bean
    public org.springframework.context.MessageSource messageSource() {
        org.springframework.context.support.ResourceBundleMessageSource messageSource = 
            new org.springframework.context.support.ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
</#if>

<#if specialRequirements?? && specialRequirements?contains("限流")>
    /**
     * 接口限流配置
     */
    @Bean
    public com.github.xiaoymin.knife4j.spring.filter.ProductionSecurityFilter rateLimiterFilter() {
        // 这里只是示例，实际项目中应引入具体的限流组件
        // 如Spring Cloud Gateway的RequestRateLimiter或自定义限流实现
        return new com.github.xiaoymin.knife4j.spring.filter.ProductionSecurityFilter();
    }
</#if>
    
<#if specialRequirements?? && specialRequirements?contains("监控")>
    /**
     * 应用性能监控配置
     */
    @Bean
    public io.micrometer.core.instrument.MeterRegistry meterRegistry() {
        io.micrometer.core.instrument.simple.SimpleMeterRegistry registry = 
            new io.micrometer.core.instrument.simple.SimpleMeterRegistry();
        // 这里只是示例，实际项目中应根据需要配置监控系统如Prometheus等
        return registry;
    }
</#if>
} 